package v1

import (
	"github.com/astaxie/beego"
	"pq/models"
	"time"

	//"go/format"
	"github.com/astaxie/beego/orm"
	"pq/helper"
	"pq/service"
	"strconv"
	"strings"
)
//const IMG_GREP  = `<img[^>]*src="data:image/[^;]+;base64,([^>]+)">`
type CsTestLibItemController struct{
	TokenCheckController
}
var sis = service.SimuItemService{}
func (ctit *CsTestLibItemController) Get(){
	limit,_ := ctit.GetInt("limit",0)
	skip,_  := ctit.GetInt("skip",models.MAXROWS)
	library_id := ctit.Ctx.Input.Param(":id")
	item := new(models.PqCsTestItem)
	items,count := item.ListAll(-1,library_id,skip,limit)
	ctit.Response(items,count)
}


func (ctit *CsTestLibItemController) GetOne()  {
	id := ctit.Ctx.Input.Param(":id")
	item := new(models.PqCsTestItem)
	one := item.GetOne(id)
	 ctit.Single(one)
}

func (ctit *CsTestLibItemController) Post() {
	row := new (models.PqCsTestItem)
	row.Id,_  = ctit.GetInt("id",0)
	row.Body = ctit.GetString("body")
	row.Score,_ = ctit.GetInt("score",1)
	row.Type,_ = ctit.GetInt("type",0)
	row.Analysis = ctit.GetString("analysis","")
	row.AnswerDisplayType = ctit.GetString("answer_display_type","az")
	row.PqTestPointCategoryId,_ = ctit.GetInt("pq_test_point_category_id",0)
	row.PqCsTestLibraryId,_ = ctit.GetInt("pq_cs_test_library_id",0)
	row.State,_ = ctit.GetInt("state",1)
	row.Ordering,_ = ctit.GetInt("ordering")
	row.TabCategoryId,_ = ctit.GetInt("tab_category_id")
	row.PqCsTestResourceId,_ = ctit.GetInt("pq_cs_test_resource_id",0)
	row.DupEnabled,_ = ctit.GetInt("dup_enabled",0)
	master := models.GetMasterDb()
	if row.PqCsTestLibraryId > 0{
		r := &models.PqCsTestResource{Id:row.PqCsTestLibraryId}
		if err := master.Read(r);err == nil{
			row.PqCsTestResourceBody = r.Body
		}
	}

	id := 0
	row.Body = helper.UploadEditorImageContent(row.Body)
	row.Analysis = helper.UploadEditorImageContent(row.Analysis)
	//update
	if row.Id > 0 {
		id = row.Id
		_,err := master.QueryTable("pq_cs_test_item").Filter("id",row.Id).Update(orm.Params{
			"body" : row.Body,
			"type" : row.Type,
			"pq_test_point_category_id" : row.PqTestPointCategoryId,
			"state" : row.Score,
			"ordering" : row.Ordering,
			"analysis" : row.Analysis,
			"tab_category_id" : row.TabCategoryId,
			"dup_enabled" : row.DupEnabled,
		})
		if err != nil {
			beego.Error(err)
			ctit.Fail(err.Error(),"")
			return
		}
	} else {
		//材料题
		if row.Type == 2 {
			resource := new(models.PqCsTestResource)
			resource.Body = row.Body
			resource.PqCsTestLibraryId = row.PqCsTestLibraryId
			ins, err := master.Insert(resource)
			if err != nil {
				beego.Error(err)
				ctit.Fail(err.Error(), "")
				return
			}
			id = int(ins)

		} else{
			ins, err := master.Insert(row)
			if err != nil {
				beego.Error(err)
				ctit.Fail(err.Error(), "")
				return
			}
			id = int(ins)
		}
	}
	res := map[string]interface{}{}
	res["id"] = id
	ctit.Single(res)
}

func (ctit *CsTestLibItemController) Del(){
	id := ctit.Ctx.Input.Param(":id")
	master := models.GetMasterDb()
	//slave := models.GetSlaveDb()
	//item := new (models.PqCsTestItem)
	//item.State = -1
	if _,err := master.QueryTable("pq_cs_test_item").Filter("id",id).Update(orm.Params{
		"state" : -1,
	});err != nil{
		ctit.Fail("Deleted fail","")
	}
	ctit.Success("Deleted Successfully")
}
func (ctit CsTestLibItemController) GetSimu(){
	id := ctit.Ctx.Input.Param(":simu_id")
	lib := new(models.PqCsSimuLibrary)
	nodes := lib.GetOne(id)
	//if len(nodes) > 1{
	ctit.Single(nodes[0])
	//}
}
func (ctit *CsTestLibItemController) GetSimuWithResource(){
	simu_id := ctit.Ctx.Input.Param(":id")
	tm := ctit.GetString("tm")
	ss := service.SimuItemService{}
	items,total := ss.GetSimuWithResrouce(simu_id,tm)
	if len(items) <= 0{

	}
	ctit.Response(items,total)
}

func (ctit CsTestLibItemController) UpdateSimu(){
	id := ctit.Ctx.Input.Param(":simu_id")
	lib := new(models.PqCsSimuLibrary)
	if lib.UpdateOne(id,orm.Params{
		"last_stop_time" : ctit.GetString("last_stop_time"),
	}){
		ctit.Success("Update successfully")
	}
	ctit.Fail("Update fail","")
}
func (ctit CsTestLibItemController) Compo(){
	master := models.GetMasterDb()
	slave := models.GetSlaveDb()
	item := new(models.PqCsTestItem)
	var randItems [][]orm.Params

	var user models.PqUser
	_ = slave.QueryTable("pq_user").Filter("id", ctit.Uid).One(&user)

	simu := new(models.PqCsSimuLibrary)
	simu.State = 1
	simu.SimuType = 3
	simu.PqTestCategoryId = user.PqTestCategoryId
	simu.PqUserId,_ = strconv.Atoi(ctit.Uid)
	simu.ModuleType = 0
	simu.IsDone = 0
	simu.TestType = 2
	simu.LastStopTime = 0
	//simu.LibraryId = testId
	simu.IsDone = 1
	simu.Title = "组卷模考"
	ins,err := master.Insert(simu)
	if err != nil {
		ctit.Response(nil,0)
	}
	randItems = item.ListRandomCom(user)
	var od = 0
	//log.Success(fmt.Sprintf("~~~~%#v~~~~~",randItems))
	for _,sectionItem := range randItems{
		for _,item := range sectionItem{
			od = od + 1
			simuItem := new (models.PqCsSimuItemConnection)
			itemId,_ := strconv.Atoi(item["id"].(string))
			insItemId := int(itemId)
			simuItem.PqCsTestItemId = insItemId
			simuItem.IsAnswered = 0
			simuItem.IsAnswerRight = 0
			simuItem.PqCsTestSimuLibraryId = int(ins)
			simuItem.Ordering = od
			tabCategoryId := item["tab_category_id"]
			resourceId := item["pq_cs_test_resource_id"]
			if tabCategoryId != nil {
				simuItem.TabCategoryId,_ = strconv.Atoi(item["tab_category_id"].(string))
			}
			if resourceId != nil {
				simuItem.ResourceId,_ = strconv.Atoi(item["pq_cs_test_resource_id"].(string))
			}
			_,_ = master.Insert(simuItem)
		}
	}
	//重新排序,让resrouce_id相同的排在一起
	//go func() {
		sis.ReOrder(int(ins))
	//}()
	ctit.Single(ins)
}
func (ctit CsTestLibItemController) Real(){
	master := models.GetMasterDb()
	slave := models.GetSlaveDb()
	testId,_ := ctit.GetInt("test_id")
	var PqCsLib  models.PqCsTestLibrary
	var items []orm.Params
	_ = slave.QueryTable("pq_cs_test_library").Filter("id", testId).One(&PqCsLib)
	//1.create new simu , category = user's test category setting
	simu := new(models.PqCsSimuLibrary)
	simu.State = 1
	simu.SimuType = 1
	simu.PqTestCategoryId = PqCsLib.PqTestCategoryId
	simu.PqUserId,_ = strconv.Atoi(ctit.Uid)
	simu.ModuleType = 0
	simu.IsDone = 0
	simu.TestType = 3
	simu.LastStopTime = 0
	simu.LibraryId = testId
	simu.IsDone = 1
	//if simu.TestType == 0 {
		simu.Title = PqCsLib.Title
	//}
	ins,err := master.Insert(simu)
	beego.Warning(err)
	if err != nil {
		ctit.Response(nil,0)
	}
	//2.list items
	//order by num
	_, _ = slave.QueryTable("pq_cs_test_item").Filter("pq_cs_test_library_id", testId).Filter("state", 1).OrderBy("ordering").Values(&items)
	var od = 0
	for _,item := range items{
		od = int(item["Ordering"].(int64))
		simuItem := new (models.PqCsSimuItemConnection)
		//beego.Warning(item["id"].(string))
		itemId := item["Id"].(int64)
		insItemId := int(itemId)
		simuItem.PqCsTestItemId = insItemId
		simuItem.IsAnswered = 0
		simuItem.IsAnswerRight = 0
		simuItem.PqCsTestSimuLibraryId = int(ins)
		simuItem.Ordering = od
		tabCategoryId := item["TabCategoryId"]
		resourceId := item["PqCsTestResourceId"]
		if tabCategoryId != nil {
			simuItem.TabCategoryId = int(item["TabCategoryId"].(int64))
		}
		if resourceId != nil {
			simuItem.ResourceId = int(item["PqCsTestResourceId"].(int64))
		}
		_,_ = master.Insert(simuItem)
		//item["simu_item_id"] = sins
		//item["is_answered"] = 0
		//item["is_answer_right"] = 0
		//item["ordering"] = ik
	}
	//3.create simu items connecto to items
	//TODO :: return ins to let client site redirect to simu test page
	//ctit.Response(items,amount)

	ctit.Single(ins)

}

func (ctit CsTestLibItemController) Spirit(){
	master := models.GetMasterDb()
	slave := models.GetSlaveDb()
	testId,_ := ctit.GetInt("test_id")
	var PqCsLib  models.PqCsTestLibrary
	var items []orm.Params
	_ = slave.QueryTable("pq_cs_test_library").Filter("id", testId).One(&PqCsLib)
	//1.create new simu , category = user's test category setting
	simu := new(models.PqCsSimuLibrary)
	simu.State = 1
	simu.SimuType = 1
	simu.PqTestCategoryId = PqCsLib.PqTestCategoryId
	simu.PqUserId,_ = strconv.Atoi(ctit.Uid)
	simu.ModuleType = 0
	simu.IsDone = 0
	simu.TestType = 3
	simu.LastStopTime = 0
	simu.LibraryId = testId
	simu.IsDone = 1
	//if simu.TestType == 0 {
	simu.Title = PqCsLib.Title
	//}
	ins,err := master.Insert(simu)
	beego.Warning(err)
	if err != nil {
		ctit.Response(nil,0)
	}
	//2.list items
	_, _ = slave.QueryTable("pq_cs_test_item").Filter("pq_cs_test_library_id", testId).Values(&items)

	for ik,item := range items{
		simuItem := new (models.PqCsSimuItemConnection)
		//beego.Warning(item["id"].(string))
		itemId := item["Id"].(int64)
		insItemId := int(itemId)
		simuItem.PqCsTestItemId = insItemId
		simuItem.IsAnswered = 0
		simuItem.IsAnswerRight = 0
		simuItem.PqCsTestSimuLibraryId = int(ins)
		simuItem.Ordering = ik + 1
		tabCategoryId := item["TabCategoryId"]
		resourceId := item["PqCsTestResourceId"]
		if tabCategoryId != nil {
			simuItem.TabCategoryId = int(item["TabCategoryId"].(int64))
		}
		if resourceId != nil {
			simuItem.ResourceId = int(item["PqCsTestResourceId"].(int64))
		}
		sins,_ := master.Insert(simuItem)
		item["simu_item_id"] = sins
		item["is_answered"] = 0
		item["is_answer_right"] = 0
		item["ordering"] = ik
	}
	//3.create simu items connecto to items
	//TODO :: return ins to let client site redirect to simu test page
	//ctit.Response(items,amount)

	ctit.Single(ins)

}

func (ctit CsTestLibItemController) Random(){
	master := models.GetMasterDb()
	slave  := models.GetSlaveDb()
	amount := ctit.Ctx.Input.Param(":amount")
	item := new(models.PqCsTestItem)
	//1.create new simu , category = user's test category setting
	var user models.PqUser
	_ = slave.QueryTable("pq_user").Filter("id", ctit.Uid).One(&user)
	simu := new(models.PqCsSimuLibrary)
	simu.State = 1
	simu.PqTestCategoryId = user.PqTestCategoryId
	simu.PqUserId,_ = strconv.Atoi(ctit.Uid)
	simu.ModuleType = 0
	simu.IsDone = 0
	simu.TestType = 0
	simu.LastStopTime = 0
	if simu.TestType == 0 {
		simu.Title = "快速智能练习"
	}
	ins,err := master.Insert(simu)
	if err != nil {
		ctit.Response(nil,0)
	}
	//2.list random n items
	items := item.ListRandom(user,amount)

	for ik,item := range items{
		simuItem := new (models.PqCsSimuItemConnection)
		//beego.Warning(item["id"].(string))
		itemId := item["id"].(string)
		insItemId,_ := strconv.Atoi(itemId)
		simuItem.PqCsTestItemId = insItemId
		simuItem.IsAnswered = 0
		simuItem.IsAnswerRight = 0
		simuItem.PqCsTestSimuLibraryId = int(ins)
		simuItem.Ordering = ik + 1
		_,_ = master.Insert(simuItem)
		//item["simu_item_id"] = sins
		//item["is_answered"] = 0
		//item["is_answer_right"] = 0
		//item["ordering"] = ik
	}
	//3.create simu items connecto to items
	//TODO :: return ins to let client site redirect to simu test page
	//ctit.Response(items,amount)

	ctit.Single(ins)
	//slave := models.GetSlaveDb()
	//slave.Raw(`SELECT * FROM pq_cs_test_item
	//				WHERE id >= (SELECT floor(RAND() * (SELECT MAX(id) FROM pq_cs_test_item)))
	//				ORDER BY id LIMIT 3;`
	//)
}
func (ctit *CsTestLibItemController) RandomZx(){
	master := models.GetMasterDb()
	slave := models.GetSlaveDb()
	amount := ctit.Ctx.Input.Param(":amount")
	point_cate_id,_ := ctit.GetInt("point_id",1)
	item := new(models.PqCsTestItem)
	var user models.PqUser
	_ = slave.QueryTable("pq_user").Filter("id", ctit.Uid).One(&user)
	//1.create new simu , category = user's test category setting
	simu := new(models.PqCsSimuLibrary)
	simu.State = 1
	simu.PqTestCategoryId = user.PqTestCategoryId
	simu.PqUserId,_ = strconv.Atoi(ctit.Uid)
	simu.ModuleType = 0
	simu.IsDone = 0
	simu.TestType = 1
	simu.SimuType = 2
	simu.LastStopTime = 0
	//if simu.TestType == 0 {
		simu.Title = "单项练习"
	//}
	ins,err := master.Insert(simu)
	if err != nil {
		ctit.Response(nil,0)
	}

	///2. get specific category
	//3.list random n items
	am,_ := strconv.Atoi(amount)
	items := item.ListRandomZx(user,point_cate_id,am)

	for ik,item := range items{
		simuItem := new (models.PqCsSimuItemConnection)
		//beego.Warning(item["id"].(string))
		itemId := item["id"].(string)
		insItemId,_ := strconv.Atoi(itemId)
		simuItem.PqCsTestItemId = insItemId
		simuItem.IsAnswered = 0
		simuItem.IsAnswerRight = 0
		simuItem.PqCsTestSimuLibraryId = int(ins)
		simuItem.Ordering = ik+1
		sins,_ := master.Insert(simuItem)
		item["simu_item_id"] = sins
		item["is_answered"] = 0
		item["is_answer_right"] = 0
		item["ordering"] = ik
	}
	//3.create simu items connecto to items
	//TODO :: return ins to let client site redirect to simu test page
	//ctit.Response(items,amount)

	ctit.Single(ins)
}
func (ctit *CsTestLibItemController) ListSimuItems(){
	simu_id := ctit.Ctx.Input.Param(":id")
	lib := new(models.PqCsSimuLibrary)
	items := lib.GetSimuItems(simu_id)
	ctit.Response(items,len(items))
}

func (ctit *CsTestLibItemController) ListSpirit(){
	slave := models.GetSlaveDb()
	var user models.PqUser
	var nodes []orm.Params
	_ = slave.QueryTable("pq_user").Filter("id", ctit.Uid).One(&user)
	var testCategory models.PqTestCategory
	_ = slave.QueryTable(`pq_test_category`).Filter("id", user.PqTestCategoryId).One(&testCategory)
	areaCode := user.AreaCode
	if testCategory.Code == "GK" {
		areaCode = ""
	}
	// 省考则找到省级code，并找到相应的真题
	if testCategory.Code == "SK" {
		var area models.Area
		_ = slave.QueryTable(`area`).Filter("area_code", areaCode).One(&area)
		areaCode = area.ParentCode
	}
	_30minute,_ := time.ParseDuration("-0.5h")
	nowTime := time.Now().Add(_30minute).Format("2006-01-02 15:04:05")
	_, _ = slave.Raw(`select pl.*,pl.spirit_start as beginning,pl.spirit_end as end from pq_cs_test_library pl
	inner join pq_test_category ptc on ptc.id = pl.pq_test_category_id
    where is_spirit=1 and pl.pq_test_category_id=? and pl.area_code=? and pl.spirit_start > ?  and pl.state=1 and ptc.lft <= ? and ptc.rgt >= ?
    order by spirit_start asc limit 1`, user.PqTestCategoryId,areaCode,nowTime,testCategory.Lft,testCategory.Rgt).Values(&nodes)
	if len(nodes) > 0 {
		var final = map[string] interface{}{}
		final["id"],_ = strconv.Atoi(nodes[0]["id"].(string))
		final["score"],_ = strconv.Atoi(nodes[0]["score"].(string))
		final["hard_rate"],_ = strconv.Atoi(nodes[0]["hard_rate"].(string))
		final["title"] = nodes[0]["title"].(string)
		final["desc"] = nodes[0]["desc"].(string)
		final["beginning"] = nodes[0]["spirit_start"].(string)
		final["end"] = nodes[0]["spirit_end"].(string)
		final["average_point"],_ = strconv.Atoi(nodes[0]["average_point"].(string))
		final["test_count"],_ = strconv.Atoi(nodes[0]["test_count"].(string))
		final["item_amount"],_ = strconv.Atoi(nodes[0]["item_amount"].(string))
		ctit.Response(final, 1)
	} else {
		ctit.Response(nil, 0)
	}
}

func (ctit *CsTestLibItemController) AnswerSimuItem(){
	conn_id := ctit.Ctx.Input.Param(":conn_id")
	//item := new(models.PqCsTestItem)
	slave := models.GetSlaveDb()
	master := models.GetMasterDb()
	idstr := ctit.GetString("idstr")
	idstrSplit := strings.Split(idstr,",")
	//check if user's answer's correct
	var ans []orm.Params
	_, _ = slave.QueryTable("pq_test_item_answer").Filter("id__in", idstrSplit).Values(&ans)
	correct := true
	for _,it := range ans{
		correct = correct && (it["IsRightAnswer"].(int64) == 1)
	}
	var ups orm.Params
	if correct {
		ups = orm.Params{
			"is_answer_right" : "1",
			"is_answered" : "1",
			"answer_choose_data" : idstr,
		}
	}else{
		ups = orm.Params{
			"is_answer_right" : "0",
			"is_answered" : "1",
			"answer_choose_data" : idstr,
		}
	}
	_, _ = master.QueryTable("pq_cs_simu_item_connection").Filter("id", conn_id).Update(ups)

	//if !item.SaveSimuAnwsers(conn_id,idstrSplit){
	//	ctit.Fail("Fail to save record","")
	//}
	ctit.Success("Save record successfully")
	//conn.AnswerChooseData =
}
func (ctit *CsTestLibItemController) StoreResource(){
	resource := new (models.PqCsTestResource)
	resource.Id,_ = ctit.GetInt("id")
	resource.Body = ctit.GetString("body")
	resource.Body = helper.UploadEditorImageContent(resource.Body)
	resource.PqCsTestLibraryId,_ = ctit.GetInt("library_id")
	master := models.GetMasterDb()
	if resource.Id > 0 {
		_,err := master.QueryTable("pq_cs_test_resource").Filter("id",resource.Id).Update(orm.Params{
			"body" : resource.Body,
		})
		if err != nil {
			beego.Error(err)
			ctit.Fail(err.Error(),"")
			return
		}
		ctit.Success("Updated successfully")
	}else{
		_, err := master.Insert(resource)
		if err != nil {
			beego.Error(err)
			ctit.Fail(err.Error(),"")
			return
		}
	}
	ctit.Success("created successfully")
}
func (ctit CsTestLibItemController) GetResource(){
	lib_id := ctit.Ctx.Input.Param(":id")
	item := new (models.PqCsTestItem)
	nodes := item.ListSimuResource(lib_id)
	//beego.Warning(nodes)
	ctit.Response(nodes,len(nodes))
}
//上次练习
func (ctc CsTestLibController) GetLastSimu(){

}
func (ctit *CsTestLibItemController) Option(){
	ctit.Fail("Options invoke","")
}
func (ctit *CsTestLibItemController) ImportResourceSubject(){
	startNum,_ := ctit.GetInt("start_num",0)
	endNum ,_ := ctit.GetInt("end_num",0)
	libId ,_ := ctit.GetInt("lib_id",0)
	resourceId ,_ := ctit.GetInt("resource_id",0)
	if endNum <= startNum {
		ctit.Fail("请正确设置题号","")
		return
	}
	resourceService := service.NewResourceService()
	for i:= startNum;i <= endNum ; i++{
		//beego.Warning(i)
		resourceService.ImportSubjectByNum(libId,resourceId,i)
	}
	ctit.Success("导入成功")
}

func(ctit *CsTestLibItemController) SetToResrouce(){
	subjectId , _ := ctit.GetInt("item_id")
	subjectService := service.NewSubjectService()
	subjectService.SetToResource(subjectId)
	ctit.Success("成功转成材料题")
}

func (ctit *CsTestLibItemController) DelResource(){
	resourceId,_  := strconv.Atoi(ctit.Ctx.Input.Param(":id"))
	resourceService := service.NewResourceService()
	_,err := resourceService.Delete(resourceId)
	if err != nil{
		ctit.Fail("删除失败","")
	}
	ctit.Success("删除成功!")
}

func (ctit *CsTestLibItemController) UpdateCollect(){
	connId,_ := strconv.Atoi(ctit.Ctx.Input.Param(":id"))
	val , _ := ctit.GetInt("val")
	itemService := service.SimuItemService{}
	itemService.Collected(connId,val, ctit.Uid)
	ctit.Success("更新成功")
}